﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;

namespace Auction_Web
{
    public class ChatTask
    {
        public ManualResetEvent waitEvent;//WaitHandle，用于阻塞当前请求，等待新消息通知
        public ChatNowDelegate _chatNow;//通知的回调方法
        public string _lastSource;//最后收到的消息源
        public string _lastMessage;//最后收到的消息

        private WaitCallback _proc = null;//异步执行的实际方法指针/委托
        private HttpContext _context;//当前请求上下文

        public delegate void ChatNowDelegate(string source, string msg);//回调消息通知的委托。
        public ChatTask(HttpContext context)
        {
            _context = context;
            waitEvent = new ManualResetEvent(false);//默认为阻塞，等待wait方法
        }

        //异步页面的任务启动方法
        public IAsyncResult OnBegin(object sender, EventArgs e,
            AsyncCallback cb, object extraData)
        {
            _proc = new WaitCallback(ChatInvokeProc);
            string user = (string)extraData;
            Thread.CurrentThread.Name = "上下文线程" + user;
            //用户处理，不存在则增加，即为登录
            if (!globalCache.userCache.ContainsKey(user))
            {
                globalCache.userCache.Add(user, this);
            }
            else
            {
                globalCache.userCache[user] = this;
            }
            //开始异步执行，这里会开启一个新的辅助线程
            return _proc.BeginInvoke(extraData, cb, extraData);
        }

        //异步页面的任务结束方法
        public void OnEnd(IAsyncResult ar)
        {
            //放弃异步执行
            _proc.EndInvoke(ar);
        }
        //如果异步任务执行超时的对应处理，即页面中的asynctimeout设置的时间到达且任务尚未返回。
        public void OnTimeout(IAsyncResult ar)
        {
            //应该发条应答，偷懒了。呵呵
        }

        private void ChatInvokeProc(object param)
        {
            Thread.CurrentThread.Name = "异步线程" + param.ToString();
            if (waitEvent.WaitOne(20 * 1000))//阻塞线程20秒，或等到wait的释放
            {
                if (_lastSource != string.Empty && _lastMessage != string.Empty)
                {
                    if (_chatNow != null)
                        _chatNow(_lastSource, _lastMessage);//回调页面方法，页面继续执行
                }
            }
            else
            {
                _lastSource = string.Empty;
                _lastMessage = string.Empty;

            }
        }
    }
}